package com.aecc.api.controller;

import java.security.KeyPair;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.aecc.api.base.BaseController;
import com.aecc.api.config.CustomEncryptPropertity;
import com.aecc.api.config.CustomTestPropertity;
import com.aecc.api.model.ResultModel;
import com.aecc.api.model.TokenEntity;
import com.aecc.api.util.JSONUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SymmetricCrypto;


@RestController
@RequestMapping("/api/token")
public class TokenController extends BaseController {
	@Autowired
	private CustomTestPropertity testPropertity;
	@Autowired
	private CustomEncryptPropertity encryptPropertity;
	
	/**
	 * 获取通用sm2加密公钥，获取token时对key加密使用
	 * @return
	 */
	@GetMapping("/publicKey")
	public ResponseEntity<ResultModel> getPublicKey() {
		return this.Resp200(ResultModel.success(encryptPropertity.getSm2PublicKey()));
	}
	
	/**
	 * 获取token
	 * @param key
	 * @return
	 */
	@PostMapping("/get")
	public ResponseEntity<ResultModel> getToken(@RequestBody Map<String, Object> params) {
		String key = "";
		if(!CollectionUtils.isEmpty(params) && params.containsKey("key") && StringUtils.isNotBlank(params.get("key").toString())) {
			String keyEncrypt = params.get("key").toString();
			try {
				SM2 sm2 = SmUtil.sm2(encryptPropertity.getSm2PrivateKey(), null);
				key = StrUtil.utf8Str(sm2.decryptFromBcd(keyEncrypt, KeyType.PrivateKey));
			} catch (Exception e) {
				return this.Resp200(ResultModel.fail("非法请求：解密key异常"));
			}
		}
		if(!StringUtils.equals(testPropertity.getKey(), key) && checkKey(key)) {
			return this.Resp200(ResultModel.fail("请求key不合法"));
		}
		LocalDateTime nowTime = LocalDateTime.now();
		nowTime = nowTime.plusHours(encryptPropertity.getTokenValidLength());
		KeyPair pair = SecureUtil.generateKeyPair("SM2");
		byte[] privateKey = pair.getPrivate().getEncoded();
		byte[] publicKey = pair.getPublic().getEncoded();
		
		TokenEntity token = new TokenEntity(key, nowTime, Base64.toBase64String(privateKey));
		String tokenStr = JSONUtil.toJSONString(token);
		SymmetricCrypto sm4 = SmUtil.sm4(Base64.decode(encryptPropertity.getSm4Key()));
		Map<String, Object> resMap = new HashMap<>();
		resMap.put("token", sm4.encryptHex(tokenStr));
		resMap.put("expTime", nowTime);
		resMap.put("publicKey", Base64.toBase64String(publicKey));
		return this.Resp200(ResultModel.success(resMap));
	}
	
	/**
	 * 判断key是否是下发的有效key
	 * @param key
	 * @return
	 */
	private Boolean checkKey(String key) {
		// 去数据库中查询，此处未实现因此返回false
		return false;
	}
	
}
